iT邦幫忙

2023 iThome 鐵人賽

DAY 1
0
自我挑戰組

Django系列 第 13

Day13~Django 漫漫長路- 入木三分serializer-part1

  • 分享至 

  • xImage
  •  

大家好,我是Leo
今天要來講解的如何在serializer 引用 serializer/images/emoticon/emoticon30.gif
OK~~~ Let's go now!!!


如果我們今天要製作一個auth list內要包含的是users、user_certificate及user_photo的資訊
也就是說有一個objects裡面的欄位其中有一欄是user_certificate,一欄是user_photo
對應的values是[obj,obj,obj]
而期望把user_certificate、user_photo id對應的欄位單獨取出來變成一個list的型式

確認資料庫有無資料

概念圖如下(黃色的部份是我們希望回傳的欄位)
https://ithelp.ithome.com.tw/upload/images/20230112/201548539O59w26sTn.jpg

table user_certificates
https://ithelp.ithome.com.tw/upload/images/20230112/20154853oFSmwgAI0L.jpg

table user_photo
https://ithelp.ithome.com.tw/upload/images/20230112/20154853ac8eLwi1c6.jpg

確認有無資料及相關ForeignKey id


Serializers

serializers/user_list_ser.py

from rest_framework import serializers
from website.models import (
    Users,
    User_Photo,
    User_Certificates
)
from django.contrib.auth.models import User

class PhotoListSerializer(serializers.ModelSerializer):
    class Meta:
        model = User_Photo
        exclude =('created_at','deleted_at')

class PhotoIdsSerializer(serializers.ModelSerializer):
    class Meta:
        model = User_Photo
        fields = ('id',)

    def to_representation(self, instance):
        return instance.id


class CertificateListSerializer(serializers.ModelSerializer):
    class Meta:
        model = User_Certificates
        exclude = ('created_at', 'deleted_at')

class CertificateIdsSerializer(serializers.ModelSerializer):
    class Meta:
        model = User_Certificates
        exclude = ('created_at', 'deleted_at')

    def to_representation(self, instance):
        return instance.id


class UserListSerializer(serializers.ModelSerializer):
    userName = serializers.ReadOnlyField(source='auth_user.username')
    firstName = serializers.ReadOnlyField(source='auth_user.first_name')
    lastName = serializers.ReadOnlyField(source='auth_user.last_name')
    email = serializers.ReadOnlyField(source='auth_user.email')
    roleName = serializers.ReadOnlyField(source='role.name')
    roleSalary = serializers.ReadOnlyField(source='role.salary')
    userPhotos = PhotoListSerializer(source='users', read_only=True, many=True, )
    userPhotosIds = PhotoIdsSerializer(source='users', read_only=True, many=True, )
    userCertificates = CertificateListSerializer(source='user_certicicate_users', read_only=True, many=True, )
    userCertificateIds = CertificateIdsSerializer(source='user_certicicate_users', read_only=True, many=True, )

    class Meta:
        model = Users
        fields = ("id",
                  "status",
                  "userName",
                  "firstName",
                  "lastName",
                  "email",
                  "tel",
                  "roleName",
                  "roleSalary",
                  "userPhotosIds",
                  "userPhotos",
                  "userCertificateIds",
                  "userCertificates"
                  )
  • userCertificates = CertificateListSerializer(source='user_certicicate_users', read_only=True, many=True, )
  • 在serializer 引用serializer,source對應model上field欄位,需跟related_name一樣,就可以引用serializer變成一個objects
  • exclude =('created_at','deleted_at') : 排除不要的欄位
  • extra_fields : 增加欄位 通常上面會再有一個fields的欄位,舉例如下
class Meta:
    model = Users
    fields = "__all__"
    extra_fields = ['userPhotosIds', 'userPhotos']
  • to_representation : 允許我們改變序列化的輸出

serializers/init.py

from .user_list_ser import *

Views

views/user_list.py

from rest_framework import permissions
from rest_framework.views import APIView
from website.models import Users
from website.serializers import UserListSerializer
from rest_framework.response import Response

class UserListAPIView(APIView):
    permission_classes = (permissions.AllowAny,)
    authentication_classes = []

    def post(self, request):
        users = Users.objects.all()
        serializer_users = UserListSerializer(
            users, many=True, context={"request": request}
        )
        return Response(serializer_users.data)

views相對就簡單許多,將objects轉成serializer在將序列化後的data回傳

views/init.py

from .user_list import *

Postman測試

https://ithelp.ithome.com.tw/upload/images/20230112/20154853trZ4FL0uB1.jpg

json資料如下

[
    {
        "id": 1,
        "status": 0,
        "userName": "leo1",
        "firstName": "leo",
        "lastName": "lee",
        "email": "a@gamil.com",
        "tel": "0987654321",
        "roleName": "parttime",
        "roleSalary": 10000.0,
        "userPhotosIds": [
            1
        ],
        "userPhotos": [
            {
                "id": 1,
                "file_name": "lbj",
                "file_path": "http://127.0.0.1:8000/media/users/1/4d27a17b-4965-4383-8373-6fba575e3096.jpg",
                "user": 1
            }
        ],
        "userCertificateIds": [
            1,
            2
        ],
        "userCertificates": [
            {
                "id": 1,
                "file_name": "leo",
                "file_path": "http://127.0.0.1:8000/media/users/1/c0c4adea-3f21-4011-a0a2-019eb92515a8.jpg",
                "user": 1
            },
            {
                "id": 2,
                "file_name": "leo",
                "file_path": "http://127.0.0.1:8000/media/users/1/110e6360-c3a1-4619-b855-282242a55c5e.jpg",
                "user": 1
            }
        ]
    },
    {
        "id": 2,
        "status": 0,
        "userName": "leo",
        "firstName": "leo",
        "lastName": "lee",
        "email": "a@gamil.com",
        "tel": "0987654321",
        "roleName": "parttime",
        "roleSalary": 10000.0,
        "userPhotosIds": [
            3
        ],
        "userPhotos": [
            {
                "id": 3,
                "file_name": "lin",
                "file_path": "http://127.0.0.1:8000/media/users/2/e5316f6e-4410-4e93-a7f7-9bf5ff3831cc.jpg",
                "user": 2
            }
        ],
        "userCertificateIds": [
            3
        ],
        "userCertificates": [
            {
                "id": 3,
                "file_name": "leo2",
                "file_path": "http://127.0.0.1:8000/media/users/2/53f26df3-0213-4d02-aeb2-1e4a3c8816b6.jpg",
                "user": 2
            }
        ]
    },
    {
        "id": 3,
        "status": 0,
        "userName": "leo2",
        "firstName": "leo2",
        "lastName": "lee2",
        "email": "a@gamil.com",
        "tel": "0987654321",
        "roleName": "parttime",
        "roleSalary": 10000.0,
        "userPhotosIds": [
            2
        ],
        "userPhotos": [
            {
                "id": 2,
                "file_name": "yun",
                "file_path": "http://127.0.0.1:8000/media/users/3/6a5a0079-a2c3-4647-8ad0-0d1ba05afd5d.jpg",
                "user": 3
            }
        ],
        "userCertificateIds": [],
        "userCertificates": []
    },
    {
        "id": 4,
        "status": 0,
        "userName": "leo3",
        "firstName": "leo3",
        "lastName": "lee3",
        "email": "a@gamil.com",
        "tel": "0987654321",
        "roleName": "engineer",
        "roleSalary": 20000.0,
        "userPhotosIds": [],
        "userPhotos": [],
        "userCertificateIds": [],
        "userCertificates": []
    },
    {
        "id": 5,
        "status": 0,
        "userName": "leo4",
        "firstName": "leo4",
        "lastName": "lee4",
        "email": "a@gamil.com",
        "tel": "0987654321",
        "roleName": "engineer",
        "roleSalary": 20000.0,
        "userPhotosIds": [],
        "userPhotos": [],
        "userCertificateIds": [],
        "userCertificates": []
    },
    {
        "id": 6,
        "status": 0,
        "userName": "leo5",
        "firstName": "leo5",
        "lastName": "lee5",
        "email": "a@gamil.com",
        "tel": "0987654321",
        "roleName": "manage",
        "roleSalary": 30000.0,
        "userPhotosIds": [],
        "userPhotos": [],
        "userCertificateIds": [],
        "userCertificates": []
    }
]

今天透過serializer將我們要的fields欄位全部回傳回來,也不需要做什麼邏輯比對,是不是很方便又愉快
明天我想介紹的是serializer的其他種用法
我們明天見,各位掰掰~~~/images/emoticon/emoticon29.gif


上一篇
Day12~Django 漫漫長路- 知曉filter,知曉篩選真理
下一篇
Day14~Django 漫漫長路- 入木三分serializer-part2
系列文
Django30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言